nix debug spurrious rebuilds
2023-09-27 · 2 min read
I have a Rust workspace full of cargo crates (and other things). Using ipetkov/crane
, the workspace dependencies should only rebuild if the Cargo.toml
or Cargo.lock
files change. Sadly that wasn't the case--touching any source file would cause a full rebuild from scratch, which takes ages.
That's where gabriella439/nix-diff
comes to the rescue: point it at two nix derivations and it'll tell you exactly what's different between them. We can use this to debug our rebuild problem.
# Add `jq` and `nix-diff` to our shell temporarily.
$ nix shell nixpkgs#jq nixpkgs#nix-diff
# Build the package twice, with an unrelated file change in between.
$ nix derivation show .#my-pkg | jq -r 'keys[0]' > before_drv
$ echo "// bump" >> ./file/causing/rebuild
$ nix derivation show .#my-pkg | jq -r 'keys[0]' > after_drv
# Let's see the difference:
$ nix-diff "$(cat before_drv)" "$(cat after_drv)"
- /nix/store/5gcg2l4bnmi3plszwrcihyshbzbd4kz1-my-pkg-0.1.0.drv:{out}
+ /nix/store/rybdvgqwrb6hjwys18yirchq1d20c8rp-my-pkg-0.1.0.drv:{out}
• The input source named `source` differs
• The input derivation named `my-pkg-deps-0.1.0` differs
- /nix/store/v523hpxdbzxwwlkgzb3hdhbclxqh7bm4-my-pkg-deps-0.1.0.drv:{out}
+ /nix/store/9a5044x65ff0jyddpzwx9gbagns4klfa-my-pkg-deps-0.1.0.drv:{out}
• The input source named `source` differs
• The environments do not match:
CFLAGS_wasm32-unknown-none=''
-isystem /nix/store/9c7h6f3ibkd4p528z3f1ydbm6lr4znpn-clang-16.0.6-lib/lib/clang/16/include -isystem
+ /nix/store/lm1p696bwrkppi746wc4hmqvf117zqsa-source/libc-shim/include
- /nix/store/hf4arhzcg3g511yzlq9lspgi9s51k5ms-source/libc-shim/include
''
Of course... I have an absolute reference to the full source in an env variable. That'll do it. Putting the sub-directory into its own tiny nix store path seems to do the trick. Thanks nix-diff
!